class Student{
    private String name;
    private int age;
    //静态成员变量
    public static String classRoom = "109";//就地初始化

    //构造方法
    public Student(){
        System.out.println("不带参数的构造方法");
    }

//    @Override
////    public String toString() {
////        return "Student{" +
////                "name='" + name + '\'' +
////                ", age=" + age +
////                '}';
////    }
//    public String toString() {
//        return "姓名：" + this.name + " " + "年龄：" + this.age;
//    }

    //(2).构造代码块
    //在方法的外面，类的里面
    {
        this.name = "ZS";
        this.age = 19;

        System.out.println("实例代码块");
    }

    //(3).静态代码块
    static{
        classRoom = "110";
        System.out.println("这是一个静态代码块！2");
    }
    static{
        classRoom = "111";
        System.out.println("这是一个静态代码块！1");
    }
    //成员方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    /**
     * 上述是对于私有的成员变量创建的接口
     */
    public void eat(){
        System.out.println(this.name + "正在吃饭");
    }
    public void show(){
        System.out.println("姓名：" + this.name + " " + "年龄：" + this.age );
    }

    public static void func(){

        System.out.println("这是一个静态的方法");
        Student student = new Student();
        student.show();

    }
}
public class Test {
    //1.static成员变量初始化
    //注意：静态成员变量一般不会放在构造方法中来初始化，构造方法中初始化的是与对象相关的实例属性
    //(1).就地初始化

    //(2)代码块的初始化
    public static void main1(String[] args) {
        //2.代码块
        //代码块的定义：
        //使用 {} 定义的一段代码称为代码块。
        //(1).普通代码块
        {
            int x = 10;
            System.out.println(x);
        }
        //System.out.println(x);
        //上述大括号中x的生命的周期是在{}中，所以出了作用域就用不了了
        int m = 12;
        System.out.println(m);
    }

    public static void main2(String[] args) {
        //调用不带参数的构造方法
        Student student = new Student();
        student.show();
        //通过打印结果可知，最先执行的是构造代码块，其次是构造方法，最后调用了show方法
    }

    public static void main3(String[] args) {
        Student student = new Student();
        student.show();//通过打印结果可知，最先执行的是静态代码块，其次是构造代码块，再次是构造方法，最后调用了show方法
    }

    public static void main4(String[] args) {
        Student student1 = new Student();
        System.out.println("=============");
        Student student2 = new Student();
        //通过结果可知道，我们发现了仅打印了一次“这是一个静态代码块！”
        //所以静态代码块仅仅执行了1次
        //为什么会执行了一次呢？
        //因为静态成员是类的属性和行为，仅仅在JVM加载类的时候并开辟空间才初始化
        //并且如果都是静态的，那么按定义的顺序执行
        /**
         * static{
         *         classRoom = "110";
         *         System.out.println("这是一个静态代码块！2");
         *     }
         *     static{
         *         classRoom = "111";
         *         System.out.println("这是一个静态代码块！1");
         *     }
         */
        //那么你可以将其看成一个，
        /**
         * static{
         *         classRoom = "110";
         *         System.out.println("这是一个静态代码块！2");
         *
         *         classRoom = "111";
         *         System.out.println("这是一个静态代码块！1");
         *     }
         */
        //这个时候就是一个静态代码块，只是将两者的按顺序进行放到一起

        //注意事项：
        //静态代码块不管生成多少个对象，其只会执行一次
        //静态成员变量是类的属性，因此是在JVM加载类时开辟空间并初始化的
        //如果一个类中包含多个静态代码块，在编译代码时，编译器会按照定义的先后次序依次执行(合并)
        //实例代码块只有在创建对象时才会执行
    }

    public static void main(String[] args) {
        System.out.println(Student.classRoom);//打印结果没有实例代码块，仅有静态代码块
        //实例(构造)代码块
        //实例代码块一定实例化对象的时候才被执行
        //静态代码块：
        //只要类被加载，那么它就会被执行
    }

    //对象的打印：
    //当成员变量特别多的时候，我们要用成员方法来进行打印，会比较麻烦和费力。
    //在类中进行写toString,双击点击generate,再点击toString，选取对象
    public static void main6(String[] args) {
        Student student = new Student();
        System.out.println(student);
    }
//本地需要用toString(源码),并且类中没有toString方法时，直接会打印地址

}